package com.yomahub.liteflow.script.javascript;

import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.script.ScriptExecuteWrap;
import com.yomahub.liteflow.script.ScriptExecutor;
import com.yomahub.liteflow.script.exception.ScriptLoadException;
import com.yomahub.liteflow.script.jsr223.JSR223ScriptExecutor;
import org.ssssssss.script.MagicScript;
import org.ssssssss.script.MagicScriptContext;

import javax.script.ScriptEngine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JavaScript脚本语言的执行器实现
 *
 * @author Bryan.Zhang
 * @since 2.9.1
 */
public class MagicScriptExecutor extends ScriptExecutor {

	private final Map<String, String> compiledScriptMap = new HashMap();

	public MagicScriptExecutor() {
	}

	public void load(String nodeId, String script) {
		this.compiledScriptMap.put(nodeId, script);
	}

	public void unLoad(String nodeId) {
		this.compiledScriptMap.remove(nodeId);
	}

	public List<String> getNodeIds() {
		return new ArrayList(this.compiledScriptMap.keySet());
	}

	public Object executeScript(ScriptExecuteWrap wrap) throws Exception {
		String compiledScript;
		if (!this.compiledScriptMap.containsKey(wrap.getNodeId())) {
			compiledScript = StrUtil.format("script for node[{}] is not loaded", new Object[]{wrap.getNodeId()});
			throw new ScriptLoadException(compiledScript);
		} else {
			compiledScript = (String)this.compiledScriptMap.get(wrap.getNodeId());
			MagicScriptContext magicScriptContext = new MagicScriptContext();
			this.bindParam(wrap, magicScriptContext::set, magicScriptContext::set);
			return MagicScript.create(compiledScript, (ScriptEngine)null).execute(magicScriptContext);
		}
	}

	public void cleanCache() {
		this.compiledScriptMap.clear();
	}

	public ScriptTypeEnum scriptType() {
		return ScriptTypeEnum.MAGICSCRIPT;
	}

	public Object compile(String script) throws Exception {
		return script;
	}
}
